package com.qinchen.service;

import com.qinchen.spring.BeanPostProcessor;
import com.qinchen.spring.Component;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author 钦尘
 * @date 2021/9/30 17:11
 * @description 自定义 BeanPostProcessor
 */
@Component
public class QinchenBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        System.out.println(bean + " -> 初始化后调用，想做什么都可以做");
        // 这里我们简单处理，模拟切面，这里判断如果是userService，则创建其对应的代理对象 bean
        if ("userService".equals(beanName)) {
            // 这里先简单用 JDK动态代理，实际 Spring 使用 cglib 动态代理，注意JDK代理必须要有接口的存在，cglib则不一定需要
            Object proxyInstance = Proxy.newProxyInstance(QinchenBeanPostProcessor.class.getClassLoader(),
                    bean.getClass().getInterfaces(), new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            // 模拟切面逻辑
                            System.out.println("执行代理对象的切面逻辑，方法" + method.getName() + "执行前");
                            Object invoke = method.invoke(bean, args);
                            System.out.println("执行代理对象的切面逻辑，方法" + method.getName() + "执行后");
                            return invoke;
                        }
                    });
            return proxyInstance;
        }
        return bean;
    }
}
